﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Text;

namespace ComToolkit.IO
{
    public static class File
    {
        public static void Copy(string sourceFileName, string destFileName, bool overwrite = false)
        {
            FileSystemObject.Get().CopyFile(sourceFileName, destFileName, overwrite);
        }

        public static AdoFileStream Create(string path) //, int bufferSize, FileOptions options);
        {
            return new AdoFileStream(path, FileMode.CreateNew, FileAccess.ReadWrite);
        }

        public static void Delete(string path)
        {
            if (Exists(path))
                FileSystemObject.Get().DeleteFile(path);
        }

        public static bool Exists(string path)
        {
            return FileSystemObject.Get().FileExists(path);
        }

        public static FileAttributes GetAttributes(string path)
        {
            throw new NotImplementedException();
        }

        public static void Move(string sourceFileName, string destFileName)
        {
            FileSystemObject.Get().MoveFile(sourceFileName, destFileName);
        }

        public static AdoFileStream Open(string path, FileMode mode, FileAccess access) //, FileShare share)
        {
            return new AdoFileStream(path, mode, access);
        }

        public static AdoFileStream OpenRead(string path) //, FileAccess access, FileShare share)
        {
            return new AdoFileStream(path, FileMode.Open, FileAccess.Read);
        }

        public static StreamReader OpenText(string path) //, FileAccess access, FileShare share)
        {
            throw new NotImplementedException();
        }

        public static AdoFileStream OpenWrite(string path, FileAccess access = FileAccess.Write) //, FileShare share)
        {
            return new AdoFileStream(path, FileMode.Open, access);
        }

        public static byte[] ReadAllBytes(string path)
        {
            using (AdoFileStream file = OpenRead(path))
            {
                using (var sr = new BinaryReader(file))
                {
                    return sr.ReadBytes((int)file.Length); //TODO: Throw exception if file to large.
                }
            }
        }

        public static string[] ReadAllLines(string path) //, Encoding encoding)
        {
            throw new NotImplementedException();
        }

        public static string ReadAllText(string path)
        {
            return ReadAllText(path, Encoding.UTF8);
        }

        public static string ReadAllText(string path, Encoding encoding)
        {
            using (AdoFileStream file = OpenRead(path))
            {
                using (var sr = new StreamReader(file, encoding))
                {
                    return sr.ReadToEnd();
                }
            }
        }

        public static void WriteAllBytes(string path, byte[] bytes)
        {
            using (var file = new AdoFileStream(path, FileMode.OpenOrCreate, FileAccess.Write))
            {
                using (var sr = new BinaryWriter(file))
                {
                    sr.Write(bytes);
                    file.Flush();
                }
            }
        }

        public static void WriteAllLines(string path, string[] contents) //, Encoding encoding)
        {
            using (var file = new AdoFileStream(path, FileMode.OpenOrCreate, FileAccess.Write))
            {
                using (var sr = new StreamWriter(file))
                {
                    foreach (string line in contents)
                    {
                        sr.WriteLine(line);
                    }
                }
            }
        }

        public static void WriteAllText(string path, string contents)
        {
            WriteAllText(path, contents, Encoding.UTF8);
        }

        public static void WriteAllText(string path, string contents, Encoding encoding)
        {
            using (var file = new AdoFileStream(path, FileMode.OpenOrCreate, FileAccess.Write))
            {
                using (var sr = new StreamWriter(file, encoding))
                {
                    sr.Write(contents);
                }
            }
        }

        public static void AppendAllLines(string path, IEnumerable<string> contents)
        {
            AppendAllLines(path, contents, Encoding.UTF8);
        }

        public static void AppendAllLines(string path, IEnumerable<string> contents, Encoding encoding)
        {
            using (var file = new AdoFileStream(path, FileMode.OpenOrCreate, FileAccess.Write))
            {
                file.Position = file.Length;
                using (var sr = new StreamWriter(file, encoding))
                {
                    foreach (string line in contents)
                    {
                        sr.WriteLine(line);
                    }
                }
            }
        }

        public static void AppendAllText(string path, string contents)
        {
            AppendAllText(path, contents, Encoding.UTF8);
        }

        public static void AppendAllText(string path, string contents, Encoding encoding)
        {
            using (var file = new AdoFileStream(path, FileMode.OpenOrCreate, FileAccess.Write))
            {
                file.Position = file.Length;
                using (var sr = new StreamWriter(file, encoding))
                {
                    sr.Write(contents);
                }
            }
        }

        public static StreamWriter AppendText(string path)
        {
            var file = new AdoFileStream(path, FileMode.OpenOrCreate, FileAccess.Write);
            file.Position = file.Length;
            return new StreamWriter(file);
        }
    }
}